use std::{error::Error, fmt::Display};

use config::ConfigError;

use crate::index::error::IndexError;

pub type BackupResult<T> = Result<T, BackupError>;

#[derive(Debug)]
pub enum BackupError {
    Config(ConfigError),
    WalkDir(walkdir::Error),
    IO(std::io::Error),
    Index(IndexError),
    Unexpected(String),
}

impl Error for BackupError { }

impl Display for BackupError {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self {
            Self::Config(e) => write!(f, "[backup config]{}", e),
            Self::WalkDir(e) => write!(f, "[backup walkdir]{}", e),
            Self::IO(e) => write!(f, "[backup io]{}", e),
            Self::Index(e) => write!(f, "[backup index]{}", e),
            Self::Unexpected(e) => write!(f, "[backup]{}", e),
        }
    }
}

impl From<ConfigError> for BackupError {
    fn from(value: ConfigError) -> Self {
        Self::Config(value)
    }
}


impl From<IndexError> for BackupError {
    fn from(value: IndexError) -> Self {
        Self::Index(value)
    }
}


impl From<walkdir::Error> for BackupError {
    fn from(value: walkdir::Error) -> Self {
        Self::WalkDir(value)
    }
}

impl From<std::io::Error> for BackupError {
    fn from(value: std::io::Error) -> Self {
        Self::IO(value)
    }
}